package com.lancoo.cvas.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lancoo.cvas.arrangecourse.ArrangeCourseService;
import com.lancoo.cvas.aspect.LogAnnotation;
import com.lancoo.cvas.entity.ClassInfo;
import com.lancoo.cvas.entity.Schedule;
import com.lancoo.cvas.entity.Student;
import com.lancoo.cvas.entity.TeachingClassWeek;
import com.lancoo.cvas.pojo.common.Deleted;
import com.lancoo.cvas.pojo.common.PageInfo;
import com.lancoo.cvas.pojo.common.ScheduleState;
import com.lancoo.cvas.pojo.dto.CheckByStudentIdBatchDTO;
import com.lancoo.cvas.pojo.dto.CheckByStudentIdDTO;
import com.lancoo.cvas.pojo.dto.SubScheduleDto;
import com.lancoo.cvas.pojo.dto.TeachingClassWeekScheduleDto;
import com.lancoo.cvas.pojo.vo.AllScheduleVo;
import com.lancoo.cvas.pojo.vo.TeachingClassSegmentDto;
import com.lancoo.cvas.pojo.vo.UnionSchedule;
import com.lancoo.cvas.service.ScheduleService;
import com.lancoo.cvas.service.TeachingClassWeekService;
import com.lancoo.cvas.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @Author: liufeng
 * @CreateTime: 2023-12-09  17:11
 * @Description:
 */
@Api(tags = "课表")
@RestController
@RequestMapping("/api/v5.0.1/web/schedule")
public class ScheduleController {

    @Resource
    private ScheduleService scheduleService;

    @Resource
    private ArrangeCourseService arrangeCourseService;
    @Resource
    private TeachingClassWeekService teachingClassWeekService;


    @ApiOperation("删除课表安排")
    @Transactional(rollbackFor = Exception.class)
    @PostMapping(value = "/removeSchedule")
    @LogAnnotation(operationType = "4", operationContent = "删除课表安排")
    public Result<Boolean> removeSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                          @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                          @ApiParam(value = "学期", required = true) @RequestParam String term,
                                          @ApiParam(value = "课表", required = true) @RequestBody List<Schedule> scheduleList) {
        scheduleService.removeSchedule(taskId, scheduleList);

        //更新冲突表 排课状态
        arrangeCourseService.manualAdjustmentUpdate(schoolId, term, taskId, null, scheduleList.get(0).getTeachingClassId());

        teachingClassWeekService.lambdaUpdate()
                .eq(TeachingClassWeek::getTeachingClassId, scheduleList.get(0).getTeachingClassId())
                .eq(TeachingClassWeek::getHourType, scheduleList.get(0).getHourType())
                .eq(TeachingClassWeek::getDeleted, Deleted.NOT.getCode())
                .set(TeachingClassWeek::getScheduleState, ScheduleState.UNARRANGE.getCode())
                .update();

        return Result.ofSuccess(true);
    }


    @ApiOperation("拆分连上和修改场地")
    @Transactional(rollbackFor = Exception.class)
    @PostMapping(value = "/subSchedule")
    @LogAnnotation(operationType = "2", operationContent = "拆分连上和修改场地")
    public Result<Boolean> subSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                          @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                          @ApiParam(value = "学期", required = true) @RequestParam String term,
                                          @ApiParam(value = "课表", required = true) @RequestBody SubScheduleDto subScheduleDto) {
        scheduleService.subSchedule(taskId, subScheduleDto);

        return Result.ofSuccess(true);
    }


    @ApiOperation("获取行政班课表")
    @GetMapping(value = "/class")
    @LogAnnotation(operationType = "3", operationContent = "查看行政班课表")
    public Result<List<TeachingClassWeekScheduleDto>> getClassSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                       @ApiParam(value = "行政班id", required = true) @RequestParam Long classId) {
        return Result.ofSuccess(scheduleService.getClassSchedule(taskId, classId));
    }

    @ApiOperation("获取教师课表")
    @GetMapping(value = "/teacher")
    @LogAnnotation(operationType = "3", operationContent = "查看教师课表")
    public Result<List<TeachingClassWeekScheduleDto>> getTeacherSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                         @ApiParam(value = "老师id", required = true) @RequestParam Long teacherId,
                                                                         @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                                         @ApiParam(value = "学期", required = true) @RequestParam String term) {
        return Result.ofSuccess(scheduleService.getTeacherSchedule(taskId, teacherId, schoolId, term));
    }


    @ApiOperation("获取教室课表")
    @GetMapping(value = "/room")
    @LogAnnotation(operationType = "3", operationContent = "查看教室课表")
    public Result<List<TeachingClassWeekScheduleDto>> getRoomSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                      @ApiParam(value = "教室id", required = true) @RequestParam Long roomId,
                                                                      @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                                      @ApiParam(value = "学期", required = true) @RequestParam String term) {
        return Result.ofSuccess(scheduleService.getRoomSchedule(taskId, roomId, schoolId, term));
    }

    @ApiOperation("获取教学班课表")
    @GetMapping(value = "/teachingClass")
    @LogAnnotation(operationType = "3", operationContent = "查看教学班课表")
    public Result<List<TeachingClassWeekScheduleDto>> getTeachingClassSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                               @ApiParam(value = "教学班id", required = true) @RequestParam Long teachingClassId) {
        return Result.ofSuccess(scheduleService.getTeachingClassSchedule(taskId, teachingClassId));
    }


    @ApiOperation("查看教学班关联课表")
    @GetMapping(value = "/getUnionSchedule")
    @LogAnnotation(operationType = "3", operationContent = "查看教学班关联课表")
    public Result<UnionSchedule> getUnionSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                  @ApiParam(value = "教室/教师id/行政班/教学班id", required = true) @RequestParam Long id,
                                                  @ApiParam(value = "1:教室 2:教师 3:行政班 4:教学班", required = true) @RequestParam Integer module,
                                                  @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                  @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                  @ApiParam(value = "课时（0101,0202）", required = false) @RequestParam(required = false) String timeCode) {
        return Result.ofSuccess(scheduleService.getUnionSchedule(taskId, id, module, schoolId, term, timeCode));
    }

    @ApiOperation("获取环节教学班列表")
    @GetMapping(value = "/segment")
    @LogAnnotation(operationType = "3", operationContent = "查看环节教学班列表")
    public Result<PageInfo<TeachingClassSegmentDto>> getTeachingClassSegment(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                             @ApiParam(value = "年级", required = false) @RequestParam(required = false) String gradeId,
                                                                             @ApiParam(value = "专业", required = false) @RequestParam(required = false) String majorId,
                                                                             @ApiParam(value = "环节类型", required = false) @RequestParam(required = false) String type,
                                                                             @ApiParam(value = "搜索关键字", required = false) @RequestParam(required = false) String keyword,
                                                                             @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                             @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<TeachingClassSegmentDto> page = new Page<>(currentPage, pageSize);
        page.setOptimizeCountSql(false);
        return Result.ofSuccess(scheduleService.getTeachingClassSegmentPage(taskId, page, gradeId, majorId, type, keyword));
    }

    @ApiOperation("获取全校行政班总表")
    @GetMapping(value = "/allClass")
    @LogAnnotation(operationType = "3", operationContent = "查看全校行政班总表")
    public Result<PageInfo<ClassInfo>> getAllClassSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                           @ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
                                                           @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                           @ApiParam(value = "年级id", required = false) @RequestParam(required = false) String gradeId,
                                                           @ApiParam(value = "班级id", required = false) @RequestParam(required = false) Long classId,
                                                           @ApiParam(value = "班级名称关键字", required = false) @RequestParam(required = false) String keyword,
                                                           @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                           @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        return Result.ofSuccess(scheduleService.getAllClassSchedule(taskId, schoolId, term, gradeId, classId, keyword, currentPage, pageSize));
    }

    @ApiOperation("获取全校教师总表")
    @GetMapping(value = "/allTeacher")
    @LogAnnotation(operationType = "3", operationContent = "查看全校教师总表")
    public Result<PageInfo<AllScheduleVo>> getAllTeacherSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                 @ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
                                                                 @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                                 @ApiParam(value = "教师名称关键字", required = false) @RequestParam(required = false) String keyword,
                                                                 @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                 @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        return Result.ofSuccess(scheduleService.getAllTeacherSchedule(taskId, schoolId, keyword, term, currentPage, pageSize));
    }

    @ApiOperation("获取全校教室总表")
    @GetMapping(value = "/allRoom")
    @LogAnnotation(operationType = "3", operationContent = "查看全校教室总表")
    public Result<PageInfo<AllScheduleVo>> getAllRoomSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                              @ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
                                                              @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                              @ApiParam(value = "校区id", required = false) @RequestParam(required = false) String campusId,
                                                              @ApiParam(value = "建筑id", required = false) @RequestParam(required = false) Integer buildingId,
                                                              @ApiParam(value = "教室名称关键字", required = false) @RequestParam(required = false) String keyword,
                                                              @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                              @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        return Result.ofSuccess(scheduleService.getAllRoomSchedule(taskId, schoolId, term, campusId, buildingId, keyword, currentPage, pageSize));
    }

    @ApiOperation("获取全校教学班总表")
    @GetMapping(value = "/allTeachingClass")
    @LogAnnotation(operationType = "3", operationContent = "查看全校教学班总表")
    public Result<PageInfo<AllScheduleVo>> getAllTeachingClassSchedule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                       @ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
                                                                       @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                                       @ApiParam(value = "课程id", required = false) @RequestParam(required = false) Long courseId,
                                                                       @ApiParam(value = "教学班名称关键字", required = false) @RequestParam(required = false) String keyword,
                                                                       @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                       @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        return Result.ofSuccess(scheduleService.getAllTeachingClassSchedule(taskId, schoolId, term, courseId, keyword, currentPage, pageSize));
    }


    @ApiOperation("导出行政班课表")
    @GetMapping(value = "/excel/class")
    @LogAnnotation(operationType = "14", operationContent = "导出行政班课表")
    public Result<Object> classScheduleToExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                               @ApiParam(value = "行政班id", required = true) @RequestParam Long classId) {
        return Result.ofSuccess(scheduleService.classScheduleToExcel(taskId, classId));
    }

    @ApiOperation("导出教师课表")
    @GetMapping(value = "/excel/teacher")
    @LogAnnotation(operationType = "14", operationContent = "导出教师课表")
    public Result<Object> teacherScheduleToExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                 @ApiParam(value = "老师id", required = true) @RequestParam Long teacherId) {
        return Result.ofSuccess(scheduleService.teacherScheduleToExcel(taskId, teacherId));
    }

    @ApiOperation("导出教室课表")
    @GetMapping(value = "/excel/room")
    @LogAnnotation(operationType = "14", operationContent = "导出教室课表")
    public Result<Object> roomScheduleToExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                              @ApiParam(value = "教室id", required = true) @RequestParam Long roomId) {
        return Result.ofSuccess(scheduleService.roomScheduleToExcel(taskId, roomId));
    }

    @ApiOperation("导出教学班课表")
    @GetMapping(value = "/excel/teachingClass")
    @LogAnnotation(operationType = "14", operationContent = "导出教学班课表")
    public Result<Object> teachingClassScheduleToExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                       @ApiParam(value = "教学班id", required = true) @RequestParam Long teachingClassId) {
        return Result.ofSuccess(scheduleService.teachingClassScheduleToExcel(taskId, teachingClassId));
    }

    @ApiOperation("导出环节全校课表")
    @GetMapping(value = "/excel/segment")
    @LogAnnotation(operationType = "14", operationContent = "导出环节全校课表")
    public Result<Object> schoolSegmentScheduleToExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                       @ApiParam(value = "环节类别id 传null全部", required = false) @RequestParam(required = false) String courseTypeId,
                                                       @ApiParam(value = "年级", required = false) @RequestParam(required = false) String gradeId,
                                                       @ApiParam(value = "专业", required = false) @RequestParam(required = false) String majorId,
                                                       @ApiParam(value = "搜索关键字", required = false) @RequestParam(required = false) String keyword) {
        return Result.ofSuccess(scheduleService.segmentToExcel(taskId, gradeId, majorId, courseTypeId, keyword));
    }


    @ApiOperation("导出班级、教室、教师、教学班总表")
    @GetMapping(value = "/excel/classTotal")
    @LogAnnotation(operationType = "14", operationContent = "导出班级、教室、教师、教学班总表")
    public Result<String> summaryScheduleToExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                 @ApiParam(value = "1:教室 2:教师 3:行政班 4:教学班", required = true) @RequestParam(required = true) Integer scheduleType,
                                                 HttpServletRequest request,
                                                 HttpServletResponse response) throws IOException {
//        ServletOutputStream out = ExcelFormatUtil.pretreatment(request, response, "summarySchedule.xlsx");
        return Result.ofSuccess(scheduleService.summaryScheduleToExcel(taskId, scheduleType));
    }

    /**
     * ============================================================================================================
     */

    @ApiOperation("根据学生id获取课表")
    @PostMapping(value = "/getScheduleByClassId")
    @LogAnnotation(operationType = "3", operationContent = "获取学生课表")
    public Result<List<TeachingClassWeekScheduleDto>> getScheduleByClassId(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                           @ApiParam(value = "学生id", required = true) @RequestParam Long studentId,
                                                                           @ApiParam(value = "已选教学班id", required = true) @RequestBody(required = false) List<Long> teachingClassIds) {
        return Result.ofSuccess(scheduleService.getScheduleByClassId(taskId, studentId, teachingClassIds));
    }


    @ApiOperation("根据学生id获取课表")
    @PostMapping(value = "/checkByStudentId")
    @LogAnnotation(operationType = "3", operationContent = "检查学生课表冲突")
    public Result<Boolean> checkByStudentId(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                            @ApiParam(value = "已选教学班id", required = true) @RequestBody(required = false) CheckByStudentIdDTO checkByStudentIdDTO) {
        return Result.ofSuccess(scheduleService.checkByStudentId(taskId,checkByStudentIdDTO));
    }


    @ApiOperation("批量检查学生课表是否存在冲突")
    @PostMapping(value = "/checkByStudentIdBatch")
    @LogAnnotation(operationType = "3", operationContent = "批量检查学生课表是否存在冲突")
    public Result<List<Student>> checkByStudentIdBatch(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                       @ApiParam(value = "已选教学班id", required = true) @RequestBody(required = false) CheckByStudentIdBatchDTO checkByStudentIdBatchDTO) {
        return Result.ofSuccess(scheduleService.checkByStudentIdBatch(taskId,checkByStudentIdBatchDTO));
    }

}
